1
|
|
|
/** global: UB */ |
2
|
|
|
|
3
|
|
|
// CASING |
4
|
|
|
|
5
|
|
|
// PROVIDES THE TABLES USED FOR FAST CASE-INSENSITIVE STRING COMPARISON |
6
|
|
|
// FOR THESE TABLES SEE "unicode uppercase lowercase tables.xlsx" |
7
|
|
|
|
8
|
|
|
// meta tables |
9
|
|
|
UB.UTF_casingRangedLowerS = [97, 224, 1072, 1121, 1169, 1377, 4304, 7681, 7841, 9424]; |
10
|
|
|
UB.UTF_casingRangedLowerE = [122, 246, 1103, 1153, 1215, 1414, 4341, 7829, 7929, 9449]; |
11
|
|
|
UB.UTF_casingRangedIncrement = [1, 1, 1, 2, 2, 1, 1, 2, 2, 1]; |
12
|
|
|
UB.UTF_casingRangedUpper = [65, 192, 1040, 1120, 1168, 1329, 4256, 7680, 7840, 9398]; |
13
|
|
|
|
14
|
|
|
// raw tables |
15
|
|
|
UB.UTF_casingRawLower = [248, 249, 250, 251, 252, 253, 254, 255, 257, 259, 261, 263, 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287, 289, 291, 293, 295, 297, 299, 301, 303, 305, 307, 309, 311, 314, 316, 318, 320, 322, 324, 326, 328, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351, 353, 355, 357, 359, 361, 363, 365, 367, 369, 371, 373, 375, 378, 380, 382, 387, 389, 392, 396, 402, 409, 417, 419, 421, 424, 429, 432, 436, 438, 441, 445, 454, 457, 460, 462, 464, 466, 468, 470, 472, 474, 476, 479, 481, 483, 485, 487, 489, 491, 493, 495, 499, 501, 507, 509, 511, 513, 515, 517, 519, 521, 523, 525, 527, 529, 531, 533, 535, 595, 596, 599, 600, 601, 603, 608, 611, 616, 617, 623, 626, 629, 643, 648, 650, 651, 658, 940, 941, 942, 943, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 995, 997, 999, 1001, 1003, 1005, 1007, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1118, 1119, 1218, 1220, 1224, 1228, 1233, 1235, 1237, 1239, 1241, 1243, 1245, 1247, 1249, 1251, 1253, 1255, 1257, 1259, 1263, 1265, 1267, 1269, 1273, 7936, 7937, 7938, 7939, 7940, 7941, 7942, 7943, 7952, 7953, 7954, 7955, 7956, 7957, 7968, 7969, 7970, 7971, 7972, 7973, 7974, 7975, 7984, 7985, 7986, 7987, 7988, 7989, 7990, 7991, 8000, 8001, 8002, 8003, 8004, 8005, 8017, 8019, 8021, 8023, 8032, 8033, 8034, 8035, 8036, 8037, 8038, 8039, 8064, 8065, 8066, 8067, 8068, 8069, 8070, 8071, 8080, 8081, 8082, 8083, 8084, 8085, 8086, 8087, 8096, 8097, 8098, 8099, 8100, 8101, 8102, 8103, 8112, 8113, 8144, 8145, 8160, 8161]; |
16
|
|
|
UB.UTF_casingRawUpper = [216, 217, 218, 219, 220, 221, 222, 376, 256, 258, 260, 262, 264, 266, 268, 270, 272, 274, 276, 278, 280, 282, 284, 286, 288, 290, 292, 294, 296, 298, 300, 302, 73, 306, 308, 310, 313, 315, 317, 319, 321, 323, 325, 327, 330, 332, 334, 336, 338, 340, 342, 344, 346, 348, 350, 352, 354, 356, 358, 360, 362, 364, 366, 368, 370, 372, 374, 377, 379, 381, 386, 388, 391, 395, 401, 408, 416, 418, 420, 423, 428, 431, 435, 437, 440, 444, 452, 455, 458, 461, 463, 465, 467, 469, 471, 473, 475, 478, 480, 482, 484, 486, 488, 490, 492, 494, 497, 500, 506, 508, 510, 512, 514, 516, 518, 520, 522, 524, 526, 528, 530, 532, 534, 385, 390, 394, 398, 399, 400, 403, 404, 407, 406, 412, 413, 415, 425, 430, 433, 434, 439, 902, 904, 905, 906, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 938, 939, 908, 910, 911, 994, 996, 998, 1000, 1002, 1004, 1006, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1038, 1039, 1217, 1219, 1223, 1227, 1232, 1234, 1236, 1238, 1240, 1242, 1244, 1246, 1248, 1250, 1252, 1254, 1256, 1258, 1262, 1264, 1266, 1268, 1272, 7944, 7945, 7946, 7947, 7948, 7949, 7950, 7951, 7960, 7961, 7962, 7963, 7964, 7965, 7976, 7977, 7978, 7979, 7980, 7981, 7982, 7983, 7992, 7993, 7994, 7995, 7996, 7997, 7998, 7999, 8008, 8009, 8010, 8011, 8012, 8013, 8025, 8027, 8029, 8031, 8040, 8041, 8042, 8043, 8044, 8045, 8046, 8047, 8072, 8073, 8074, 8075, 8076, 8077, 8078, 8079, 8088, 8089, 8090, 8091, 8092, 8093, 8094, 8095, 8104, 8105, 8106, 8107, 8108, 8109, 8110, 8111, 8120, 8121, 8152, 8153, 8168, 8169]; |
17
|
|
|
|
18
|
|
|
|
19
|
|
|
// final tables (= ranged + raw) |
20
|
|
|
UB.UTF_casingTablesMax = 9450; |
21
|
|
|
|
22
|
|
|
UB.initCasing = function(){ |
23
|
|
|
|
24
|
|
|
// exit if already initialized |
25
|
|
|
if (UB.UTF_lowerToUpper != null){ |
|
|
|
|
26
|
|
|
return; |
27
|
|
|
} |
28
|
|
|
|
29
|
|
|
// CALC CASING CONVERSION TABLES |
30
|
|
|
UB.UTF_lowerToUpper = []; |
31
|
|
|
UB.UTF_upperToLower = []; |
32
|
|
|
|
33
|
|
|
// init by mapping to self (most chars dont have an uppercase/lowercase version) |
34
|
|
|
for (var n = 0, nlast = UB.UTF_casingTablesMax;n <= nlast;n++){ |
35
|
|
|
UB.UTF_lowerToUpper[n] = n; |
36
|
|
|
UB.UTF_upperToLower[n] = n; |
37
|
|
|
} |
38
|
|
|
|
39
|
|
|
// per range |
40
|
|
|
for (var r = 0, rl = UB.UTF_casingRangedLowerS.length;r<rl;r++){ |
41
|
|
|
|
42
|
|
|
// per value in range |
43
|
|
|
var inc = UB.UTF_casingRangedIncrement[r]; |
44
|
|
|
var offset = UB.UTF_casingRangedUpper[r] - UB.UTF_casingRangedLowerS[r]; |
45
|
|
|
for (var lower = UB.UTF_casingRangedLowerS[r], lowerlast = UB.UTF_casingRangedLowerE[r];lower <= lowerlast;lower += inc){ |
46
|
|
|
|
47
|
|
|
// calc uppercase |
48
|
|
|
var upper = lower + offset; |
49
|
|
|
|
50
|
|
|
// store in table |
51
|
|
|
UB.UTF_lowerToUpper[lower] = upper; |
52
|
|
|
UB.UTF_upperToLower[upper] = lower; |
53
|
|
|
|
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
} |
57
|
|
|
|
58
|
|
|
// per raw value |
59
|
|
|
for (var n = 0, nl = UB.UTF_casingRawLower.length;n<nl;n++){ |
|
|
|
|
60
|
|
|
|
61
|
|
|
lower = UB.UTF_casingRawLower[n]; |
62
|
|
|
upper = UB.UTF_casingRawUpper[n]; |
63
|
|
|
|
64
|
|
|
// store in table |
65
|
|
|
UB.UTF_lowerToUpper[lower] = upper; |
66
|
|
|
UB.UTF_upperToLower[upper] = lower; |
67
|
|
|
|
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
// fix bug in unicode table .. "I" >> "i" |
71
|
|
|
UB.UTF_upperToLower[73] = 105; |
72
|
|
|
|
73
|
|
|
|
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
|
77
|
|
|
var arrayFuncs = { |
78
|
|
|
|
79
|
|
|
camelCaseMergeWords: function(firstCharCaps = false){ |
80
|
|
|
var words = this; |
81
|
|
|
|
82
|
|
|
// lowercase first letter |
83
|
|
|
words[0] = firstCharCaps ? words[0].firstLetterUpper() : words[0].firstLetterLower(); |
84
|
|
|
|
85
|
|
|
// loop thru all words |
86
|
|
|
var newWords = ""; |
87
|
|
|
for (var w = 0, wl = words.length;w<wl;w++){ |
88
|
|
|
var word = words[w].replace(UB.regex.Trim, ''); |
89
|
|
|
|
90
|
|
|
// cap first letter if not 1st word |
91
|
|
|
newWords += w == 0 ? word : word.firstLetterUpper(); |
|
|
|
|
92
|
|
|
} |
93
|
|
|
return newWords; |
94
|
|
|
}, |
95
|
|
|
|
96
|
|
|
none:null |
97
|
|
|
}; |
98
|
|
|
|
99
|
|
|
// register funcs |
100
|
|
|
UB.registerFuncs(Array.prototype, arrayFuncs); |
101
|
|
|
|
102
|
|
|
|
103
|
|
|
var stringFuncs = { |
104
|
|
|
|
105
|
|
|
// casing |
106
|
|
|
camelCaseSeperate: function(){ |
107
|
|
|
var camelCase = this; |
108
|
|
|
|
109
|
|
|
// loop thru all chars |
110
|
|
|
var lastUp = false; |
111
|
|
|
var lastSpace = false; |
112
|
|
|
var newName = []; |
113
|
|
|
var len = 0; |
114
|
|
|
for (var c = 0, cl = camelCase.length - 1;c <= cl;c++){ |
115
|
|
|
var char = camelCase.charAt(c); |
116
|
|
|
var charNext = c < cl ? camelCase.charAt(c + 1) : "_"; |
117
|
|
|
|
118
|
|
|
// if its a Capital ... and if prev is not also a capital ... or if the next is small |
119
|
|
|
var up = (char.toUpperCase() == char); |
120
|
|
|
var nextUp = (charNext.toUpperCase() == charNext); |
121
|
|
|
if ((up && (!lastUp || !nextUp) && !lastSpace) || char == "_") { |
122
|
|
|
|
123
|
|
|
// add a space |
124
|
|
|
if (len > 0 && newName[len - 1] != " "){ |
125
|
|
|
newName.push(" "); |
126
|
|
|
len++; |
127
|
|
|
} |
128
|
|
|
} |
129
|
|
|
lastUp = up; |
130
|
|
|
|
131
|
|
|
// add the char |
132
|
|
|
if (char != "_"){ |
133
|
|
|
newName.push(char); |
134
|
|
|
len++; |
135
|
|
|
} |
136
|
|
|
lastSpace = char == " "; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
// caps first letter |
140
|
|
|
return newName.join("").firstLetterUpper(); |
141
|
|
|
}, |
142
|
|
|
camelCaseSeperateWords: function(){ |
143
|
|
|
var camelCase = this; |
144
|
|
|
return camelCase.camelCaseSeperate().split(" "); |
145
|
|
|
}, |
146
|
|
|
camelCaseMerge: function(firstCharCaps = false){ |
147
|
|
|
var sentence = this; |
148
|
|
|
|
149
|
|
|
// exit quickly if no spaces .. no words to merge |
150
|
|
|
if (sentence.indexOf(" ") == -1) { |
151
|
|
|
if (firstCharCaps) { |
152
|
|
|
return sentence.firstLetterUpper(); |
153
|
|
|
}else{ |
|
|
|
|
154
|
|
|
return sentence; |
155
|
|
|
} |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
// merge words using camel case |
159
|
|
|
return sentence.split(" ").camelCaseMergeWords(firstCharCaps); |
160
|
|
|
}, |
161
|
|
|
firstLetterUpper: function(){ |
162
|
|
|
var str = this; |
163
|
|
|
str = str.trim(); |
164
|
|
|
return str.charAt(0).toUpperCase() + str.substr(1); |
165
|
|
|
}, |
166
|
|
|
firstLetterLower: function(){ |
167
|
|
|
var str = this; |
168
|
|
|
str = str.trim(); |
169
|
|
|
return str.charAt(0).toLowerCase() + str.substr(1); |
170
|
|
|
}, |
171
|
|
|
toSmartCase: function(){ |
172
|
|
|
var word = this; |
173
|
|
|
// home loan > Home Loan |
174
|
|
|
// PRNQ loan > PRNQ Loan |
175
|
|
|
return word.toCustomCase(";,. -_" + "\t" + "\n", true); |
176
|
|
|
}, |
177
|
|
|
toSentenceCase: function(){ |
178
|
|
|
var word = this; |
179
|
|
|
return word.toCustomCase(".", false); |
180
|
|
|
}, |
181
|
|
|
toCustomCase: function(capsAfterChars, preserveCaps = false){ |
182
|
|
|
var word = this; |
183
|
|
|
var nextCaps = true;// first char caps |
184
|
|
|
|
185
|
|
|
// per char |
186
|
|
|
var chars = word.splitChars(); |
187
|
|
|
var chars2 = []; |
188
|
|
|
for (var c = 0, cl = chars.length;c<cl;c++){ |
189
|
|
|
var ch = chars[c]; |
190
|
|
|
var added = false; |
191
|
|
|
|
192
|
|
|
// add as CAPS if wanted |
193
|
|
|
if (nextCaps) { |
194
|
|
|
nextCaps = false; |
195
|
|
|
chars2.push(ch.toUpperCase()); |
196
|
|
|
added = true; |
197
|
|
|
} |
198
|
|
|
|
199
|
|
|
// next char should have caps |
200
|
|
|
if (capsAfterChars.indexOf(ch) > -1) { |
201
|
|
|
nextCaps = true; |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
// add normally |
205
|
|
|
if (!added) { |
206
|
|
|
|
207
|
|
|
// preserve caps if wanted |
208
|
|
|
if (preserveCaps && ch.toUpperCase() == ch) { |
209
|
|
|
chars2.push(ch); |
210
|
|
|
}else { |
211
|
|
|
|
212
|
|
|
// add as lower case |
213
|
|
|
chars2.push(ch.toLowerCase()); |
214
|
|
|
} |
215
|
|
|
} |
216
|
|
|
} |
217
|
|
|
return chars2.join(""); |
218
|
|
|
}, |
219
|
|
|
toTitleCase: function(){ |
220
|
|
|
var word = this; |
221
|
|
|
// home loan > Home Loan |
222
|
|
|
// PRNQ loan > Prnq Loan |
223
|
|
|
return word.toCustomCase(";,. -_" + "\t" + "\n", false); |
224
|
|
|
}, |
225
|
|
|
toSentenceTitleCase: function(){ |
226
|
|
|
var title = this; |
227
|
|
|
var parts = []; |
228
|
|
|
var index = 0; |
229
|
|
|
|
230
|
|
|
// create regexps |
231
|
|
|
var small = "(a|an|and|as|at|but|by|en|for|if|in|of|on|or|the|to|v[.]?|via|vs[.]?)"; |
232
|
|
|
var punct = "([!\"#$%&'()*+,./:;<=>?@[\\\\\\]^_`{|}~-]*)"; |
233
|
|
|
var r1 = new RegExp("\\b([A-Za-z][a-z.'Õ]*)\\b", "g"); |
234
|
|
|
var r2 = new RegExp("[A-Za-z]\\.[A-Za-z]", ""); |
235
|
|
|
var r3 = new RegExp("\\b" + small + "\\b", "ig"); |
236
|
|
|
var r4 = new RegExp("^" + punct + small + "\\b", "ig"); |
237
|
|
|
var r5 = new RegExp("\\b" + small + punct + "$", "ig"); |
238
|
|
|
var r6 = new RegExp(" V(s?)\\. ", "ig"); |
239
|
|
|
var r7 = new RegExp("(['Õ])S\\b", "ig"); |
240
|
|
|
var split = new RegExp("[:.;?!] |(?: |^)[\"Ò]", "g"); |
241
|
|
|
|
242
|
|
|
// per word in string |
243
|
|
|
while (true) { |
244
|
|
|
var m = split.exec(title); |
245
|
|
|
|
246
|
|
|
var ToLowerCase = function(x){ |
247
|
|
|
return x.toLowerCase(); |
248
|
|
|
} |
249
|
|
|
var ToUpperCaseFirst = function(x){ |
250
|
|
|
return x.firstLetterUpper(); |
251
|
|
|
} |
252
|
|
|
|
253
|
|
|
// smart capatalize |
254
|
|
|
parts.push( title.substring(index, m ? m.index : title.length).replace(r1, function(all) { |
255
|
|
|
return r2.test(all) ? all : all.firstLetterUpper(); |
256
|
|
|
}).replace(r3, ToLowerCase).replace(r4, function (all, punct, word){ |
257
|
|
|
return punct + word.firstLetterUpper(); |
258
|
|
|
}).replace(r5, ToUpperCaseFirst)); |
259
|
|
|
|
260
|
|
|
index = split.lastIndex; |
261
|
|
|
|
262
|
|
|
if ( m ) parts.push( m[0] ); |
|
|
|
|
263
|
|
|
else break; |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
return parts.join("").replace(r6, " v$1. ").replace(r7, "$1s"); |
267
|
|
|
}, |
268
|
|
|
toCamelCase: function(){ |
269
|
|
|
var word = this; |
270
|
|
|
return word.camelCaseMerge(false); |
271
|
|
|
}, |
272
|
|
|
toPascalCase: function(){ |
273
|
|
|
var word = this; |
274
|
|
|
return word.camelCaseMerge(true); |
275
|
|
|
}, |
276
|
|
|
toURLCase: function(){ |
277
|
|
|
var path = this; |
278
|
|
|
path = path.removeAll("&"); |
279
|
|
|
path = path.removeAll("\""); |
280
|
|
|
path = path.removeAll("'"); |
281
|
|
|
path = path.removeAll(","); |
282
|
|
|
path = path.removeAll("?"); |
283
|
|
|
path = path.setSlash("/").replaceAll(" ", "-"); |
284
|
|
|
path = path.replaceAll("----", "-"); |
285
|
|
|
path = path.replaceAll("---", "-"); |
286
|
|
|
path = path.replaceAll("--", "-"); |
287
|
|
|
return path.toLowerCase(); |
288
|
|
|
}, |
289
|
|
|
pascalToCamelCase: function(){ |
290
|
|
|
var word = this; |
291
|
|
|
|
292
|
|
|
// no change if already begins with lowercase letter |
293
|
|
|
if (word.substr(0, 1).isLowercase()) { |
294
|
|
|
return word; |
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
// make the first word lowercase |
298
|
|
|
|
299
|
|
|
// if >2 chars are uppercase |
300
|
|
|
var num = word.countStartingUppercase(); |
301
|
|
|
if (num > 2) { |
302
|
|
|
|
303
|
|
|
// lowercase all uppercase chars (except the last) |
304
|
|
|
return word.firstXCharsLower(num - 1); |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
// lowercase first char only |
308
|
|
|
return word.firstLetterLower(); |
309
|
|
|
}, |
310
|
|
|
firstXCharsUpper: function(numOfChars){ |
311
|
|
|
var text = this; |
312
|
|
|
return text.setRange(0, numOfChars - 1, text.getRange(0, numOfChars - 1).toUpperCase()); |
313
|
|
|
}, |
314
|
|
|
firstXCharsLower: function(numOfChars){ |
315
|
|
|
var text = this; |
316
|
|
|
return text.setRange(0, numOfChars - 1, text.getRange(0, numOfChars - 1).toLowerCase()); |
317
|
|
|
}, |
318
|
|
|
none:null |
319
|
|
|
}; |
320
|
|
|
|
321
|
|
|
// register funcs |
322
|
|
|
UB.registerFuncs(String.prototype, stringFuncs); |